import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;


public class HMAC {
	
    // Buffer used to transport the bytes from one stream to another
	private byte[] buf = new byte[1024];
	private Mac mac;
	private int lengthOfMac;
	
	public HMAC(String key){
		try{
			mac = Mac.getInstance("HmacSHA256");
			SecretKeySpec secret = new SecretKeySpec(key.getBytes(),"HmacSHA256");
			mac.init(secret);
			lengthOfMac = mac.getMacLength();
		}catch (Exception ex) {
        }
    }
	
	public byte[] hash(String fileNameToHash, InputStream in){
		try{
			int numRead = 0;
			
			//add file name into hash
			mac.update(fileNameToHash.getBytes());
			
			//add file content into hash
			while ((numRead = in.read(buf)) >= 0){
				mac.update(buf);
	        }
			
			in.close();
			
			//return final result
			byte[] digest = mac.doFinal();
			
			StringBuffer sb = new StringBuffer();
		    for (int i = 0; i < digest.length; i++) {
		    	sb.append(Integer.toString((digest[i] & 0xff) + 0x100, 16).substring(1));
		    }

			return digest;
			
		}catch (Exception ex) {
			return null;
        }
	}
	
	public void generateHashFile(String inputFileName, String outputFileName){
        try {
                InputStream in = new FileInputStream(inputFileName);
                OutputStream out = new FileOutputStream(outputFileName);
                out.write(hash(outputFileName, in));
                
                in = new FileInputStream(inputFileName);
                int numRead = 0;
                
                while ((numRead = in.read(buf)) >= 0){
                        out.write(buf, 0, numRead);
                }
                in.close();
                out.close();
                
        } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
        }       
	}
	
	public byte[] generateHashSubFile(String inputFileName, String outputFileName, String hashedFileName){
        try {
        		byte[] HMAC = new byte[32];
        		
        		System.out.println("1: " + outputFileName + "  2: " + hashedFileName);
                InputStream in = new FileInputStream(inputFileName);
                OutputStream out = new FileOutputStream(outputFileName);
                HMAC = hash(hashedFileName, in);
                out.write(HMAC);
                
                in = new FileInputStream(inputFileName);
                int numRead = 0;
                
                while ((numRead = in.read(buf)) >= 0){
                        out.write(buf, 0, numRead);
        }
                in.close();
                out.close();
                return HMAC;
                
        } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return null;
        }       
	}	
}
